package com.carrot.gateway.uaa;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.carrot.common.core.domain.R;
import com.carrot.common.enums.ErrorCodeEnum;
import com.carrot.gateway.constant.OAuth2Constants;
import com.carrot.gateway.entity.ClientCertificate;
import com.carrot.gateway.entity.dto.LoginDto;
import com.carrot.gateway.entity.vo.TokenVo;
import com.carrot.gateway.entity.vo.UserVo;
import com.carrot.gateway.property.SecurityOAuth2Properties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

/**
 * uaa服务类
 */

@Service
@AllArgsConstructor
@Slf4j
public class UaaRequestServiceImpl implements IUaaRequestService {

    private final SecurityOAuth2Properties securityOAuth2Properties;


    @Override
    public R<TokenVo> getTokenByCode(String code, String redirectUri, String appName) {
        //TODO
        return R.ok();
    }

    @Override
    public R<UserVo> getUser(String accessToken) {
        //TODO
        return R.ok();
    }

    @Override
    public R<?> revocationToken(String token, ClientCertificate clientCertificate) {
        String clientId = clientCertificate.getClientId();
        String clientSecret = clientCertificate.getClientSecret();
        String issuerUri = clientCertificate.getAuthAddress();

        try {
            //请求认证中心获取用户
            HttpRequest request = HttpRequest.post(issuerUri + OAuth2Constants.OAUTH2_REVOKE_ENDPOINT)
                    .basicAuth(clientId, clientSecret)
                    .form("token", token);
            HttpResponse response = request.execute();
            if (HttpStatus.OK.value() == response.getStatus()) {
                return R.ok();
            }
        } catch (Exception e) {
            log.error("退出登录-请求SSO服务异常{}", e);
            return R.fail("退出登录-请求SSO服务异常");
        }

        return R.fail();
    }


    @Override
    public R<TokenVo> getTokenByPassword(LoginDto loginDTO, ClientCertificate clientCertificate) {
        String clientId = clientCertificate.getClientId();
        String clientSecret = clientCertificate.getClientSecret();
        String issuerUri = clientCertificate.getAuthAddress();
        String scope = clientCertificate.getScope();
        String body = "";
        //请求sso认证中心
        try {
            HttpRequest request = HttpRequest.post(issuerUri + OAuth2Constants.OAUTH2_TOKEN_ENDPOINT).basicAuth(clientId, clientSecret)
                    .form("grant_type", OAuth2Constants.GRANT_TYPE_PASSWORD_CODE)
                    .form("loginType", loginDTO.getLoginType())
                    .form("scope", scope)
                    .form("account", loginDTO.getAccount())
                    .form("password", loginDTO.getPassword())
                    .form("clientIp", loginDTO.getClientIp())
                    .form("appName", clientCertificate.getClientId());

            HttpResponse response = request.execute();
            body = response.body();
            return JSON.parseObject(body, R.class);
        } catch (Exception e) {
            log.error("密码模式获取token-请求SSO服务异常{},返回信息:{}", e.getMessage(), body, e);
            return R.fail("服务器开小差，请稍后重试");
        }
    }

    @Override
    public R<?> getSmsCaptcha(String phone, ClientCertificate clientCertificate) {
        String issuerUri = clientCertificate.getAuthAddress();
        String body = "";
        try {
            JSONObject params = new JSONObject();
            params.put("phone", phone);
            params.put("appName", clientCertificate.getClientId());
            HttpRequest request = HttpRequest.post(issuerUri + OAuth2Constants.SSO_LOGIN_SMS_CAPTCHA).body(params.toString());
            HttpResponse response = request.execute();
            body = response.body();
        } catch (Exception e) {
            log.error("获取验证码-请求SSO服务异常{}", e);
            return R.fail("获取验证码-请求SSO服务异常");
        }
        return JSON.parseObject(body, R.class);
    }

    @Override
    public R<TokenVo> getTokenByRefreshToken(String refreshToken, ClientCertificate clientCertificate, String clientIp) {
        String issuerUri = clientCertificate.getAuthAddress();
        String clientId = clientCertificate.getClientId();
        String clientSecret = clientCertificate.getClientSecret();
        String body = "";
        //请求sso认证中心
        try {
            HttpRequest request = HttpRequest.post(issuerUri + OAuth2Constants.OAUTH2_TOKEN_ENDPOINT).basicAuth(clientId, clientSecret)
                    .form("grant_type", OAuth2Constants.GRANT_TYPE_REFRESH_TOKEN)
                    .form("refresh_token", refreshToken)
                    .form("clientIp", clientIp);
            HttpResponse response = request.execute();
            body = response.body();
        } catch (Exception e) {
            log.error("刷新模式获取token-请求SSO服务异常{}", e.getMessage());
            return R.fail("刷新模式获取token-请求SSO服务异常");
        }
        R resultWrapper = JSON.parseObject(body, R.class);
        if (ErrorCodeEnum.CODE_OK.getCode() != resultWrapper.getCode()) {
            String msg = resultWrapper.getMsg();
            if ("invalid_grant".equals(msg)) {
                return R.fail("长时间未操作，系统退出，请重新登录！");
            } else if ("account_exception".equals(msg)) {
                return R.fail("账号在其他地方登录或被禁用，如非本人操作，请联系管理员");
            }
        }
        return resultWrapper;
    }
}
